package com.zmn.plat.admin.controller.product;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto.KvDTO;
import com.zmn.common.utils.logger.LoggerUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.office.ExcelUtil;
import com.zmn.common.utils.response.ResponseUtil;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.dictionary.ProductTitleDict;
import com.zmn.plat.manager.dictionary.ProductDict;
import com.zmn.plat.model.entity.category.BaseCategory;
import com.zmn.plat.model.entity.category.BaseCategoryQuery;
import com.zmn.plat.model.entity.channel.Channel;
import com.zmn.plat.model.entity.product.*;
import com.zmn.plat.model.entity.servcategory.ServAssCategory;
import com.zmn.plat.model.entity.servcategory.ServAssCategoryQuery;
import com.zmn.plat.model.entity.servcategory.ServCategory;
import com.zmn.plat.model.vo.product.ServProductVO;
import com.zmn.plat.model.vo.servcategory.BaseCategoryAttributeVO;
import com.zmn.plat.model.vo.servcategory.ServAssCategoryVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * 描述: 产品管理查询控制
 *
 * @author tanbiao
 * @since: 2018/11/5 22:06
 */
@Controller
@RequestMapping("/showProduct/")
public class ShowServProductListController extends ServProductBaseController {

    private Logger logger = LoggerFactory.getLogger(ShowServProductListController.class);

    /**
     * 描述: 前台产品列表
     *
     * @param query 查询实体
     * @return ModelAndView
     * @author tanbiao
     * @since 15:38 2019/9/22
     */
    @SuppressWarnings("Duplicates")
    @RequestMapping(value = "list")
    public ModelAndView list(@ModelAttribute ServProductQuery query) {
        // 前端产品类型
        query.setShowType(ProductConsts.EC_PRODUCT_TYPE);
        ModelAndView mav = new ModelAndView("product/show/list");

        try {
            ServCategory querySC = new ServCategory();
            // 服务分类
            List<ServCategory> servCategories = servCategoryService.listByQuery(querySC);

            List<BaseCategory> baseCategories = Collections.emptyList();
            if (NumberUtil.isPositiveInteger(query.getServCategId())) {
                baseCategories = servAssCategoryService.findCategoryOneByServIdAndShowType(query.getServCategId(), query.getShowType());
            }

            List<ServAssCategoryVO> baseCategoryTwoList = Collections.emptyList();
            if (NumberUtil.isPositiveInteger(query.getCategOneId())) {
                ServAssCategoryQuery queryBQ = new ServAssCategoryQuery();
                queryBQ.setServCategId(query.getServCategId());
                queryBQ.setCategOneId(query.getCategOneId());
                queryBQ.setShowType(query.getShowType());
                baseCategoryTwoList = servAssCategoryService.listByQuery(queryBQ);
            }
            // 后台产品数据
            ServProductQuery servProductQuery = new ServProductQuery();
            servProductQuery.setShowType(ProductConsts.ERP_PRODUCT_TYPE);
            List<ServProduct> backProducts = servProductService.listByQuery(servProductQuery);

            BaseCategoryQuery queryB = new BaseCategoryQuery();
            queryB.setShowType(query.getShowType());
            List<BaseCategory> baseCategorieall = baseCategoryService.listByQuery(queryB);

            List<ServProductVO> items = servProductBService.listShowVOPageByQuery(query, servCategories, baseCategorieall);

            List<Channel> channelList = channelService.listTwoLevelChannel(null, null);
            mav.addObject("channelList", channelList);

            mav.addObject("items", items);
            mav.addObject("vo", query);
            mav.addObject("servCategories", servCategories);
            mav.addObject("baseCategories", baseCategories);
            mav.addObject("baseCategoryTwoList", baseCategoryTwoList);
            mav.addObject("priceTypes", GlobalDict.getPriceTypeList());
            mav.addObject("productTypes", com.zmn.plat.common.dictionary.ProductDict.listProductTypes());
            mav.addObject("status", GlobalDict.getMasterState());
            mav.addObject("backProducts", backProducts);
            mav.addObject("bizTypeList", com.zmn.plat.common.dictionary.ProductDict.listBizType());
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return mav;
    }

    /**
     * 描述: 产品详情
     *
     * @param productId 产品ID
     * @return ModelAndView 产品详情页面
     * @author tanbiao
     * @since 15:38 2019/9/22
     */
    @RequestMapping("detail")
    public ModelAndView detail(@RequestParam(value = "productId", defaultValue = "0") Integer productId) {

        ServProduct servProduct = productId > 0 ? servProductService.findByKey(productId) : new ServProduct();
        if (productId.equals(ProductDict.ZERO)) {
            servProduct.setProductId(productId);
        }

        ModelAndView mav = new ModelAndView("product/show/detail");

        mav.addObject("servProduct", servProduct);
        return mav;
    }

    /**
     * 描述: 产品添加，修改页面 跳转方法
     *
     * @param productId 产品id
     * @return modelAndView
     * @author tanbiao
     * @since 15:38 2019/9/22
     */
    @RequestMapping(value = "addEditView")
    public ModelAndView addEditView(@RequestParam(value = "productId", defaultValue = "0") Integer productId,
                                    @RequestParam(value = "productType", defaultValue = "0") Integer productType) {

        ServProduct product = productId > ProductDict.ZERO ? servProductService.findByKey(productId) : new ServProduct();
        ModelAndView modelAndView = new ModelAndView("product/show/detail");
        ServProductVO servProductVO = new ServProductVO();

        if (Objects.isNull(product.getProductId())) {
            // 前台产品排序默认最大值＋1
            Integer maxShowSort = servProductService.findMaxShowSort();
            product.setShowSort(maxShowSort == null ? 1 : maxShowSort + 1);
        }
        BeanUtils.copyProperties(product, servProductVO);
        servProductVO.setProductType(NumberUtil.isNullOrZero(productId) ? productType : product.getProductType());

        ServCategory querySC = new ServCategory();
        querySC.setShowStatus(GlobalConsts.YES);
        List<ServCategory> servCategories = servCategoryService.listByQuery(querySC);
        // 是修改的情况下，需要将禁用的服务分类添加到集合中用于显示
        if (product.getProductId() != null) {
            ServCategory category = servCategoryService.findByKey(product.getServCategId());
            if (!category.getShowStatus().equals(GlobalConsts.YES)) {
                servCategories.add(category);
            }
        }

        List<KvDTO<Integer, String>> baseCategories = Collections.emptyList();
        List<ServAssCategoryVO> categoryVOList = Collections.emptyList();
        List<BaseCategoryAttributeVO> attrList = Collections.emptyList();
        List<FicoCategory> ficoCategoryList = ficoCategoryService.listAll();

        if (product.getProductId() != null) {
            ServAssCategoryQuery queryBQ = new ServAssCategoryQuery();
            queryBQ.setServCategId(product.getServCategId());
            queryBQ.setCategOneStatus(GlobalConsts.YES);
            queryBQ.setShowType(ProductConsts.EC_PRODUCT_TYPE);
            baseCategories = servAssCategoryService.listCateOneByQuery(queryBQ);

            BaseCategoryQuery baseCategoryQueryOne = new BaseCategoryQuery();
            baseCategoryQueryOne.setCategId(product.getCategOneId());
            List<BaseCategory> baseList = baseCategoryService.listByQuery(baseCategoryQueryOne);

            BaseCategory baseCategoryOne = CollectionUtils.isEmpty(baseList) ? null : baseList.get(0);
            if (baseCategoryOne != null && !baseCategoryOne.getStatus().equals(GlobalConsts.YES)) {
                baseCategories.add(new KvDTO<>(baseCategoryOne.getCategId(), baseCategoryOne.getName()));
            }

            ServAssCategoryQuery query = new ServAssCategoryQuery();
            query.setCategOneId(product.getCategOneId());
            query.setServCategId(product.getServCategId());
            query.setCategTwoStatus(GlobalConsts.YES);
            query.setShowType(ProductConsts.EC_PRODUCT_TYPE);
            categoryVOList = servAssCategoryService.listByQuery(query);

            BaseCategoryQuery baseCategoryQueryTwo = new BaseCategoryQuery();
            baseCategoryQueryTwo.setCategId(product.getCategId());
            List<BaseCategory> baseCategoryTwoList = baseCategoryService.listByQuery(baseCategoryQueryTwo);
            BaseCategory baseCategoryTwo = CollectionUtils.isEmpty(baseCategoryTwoList) ? null : baseCategoryTwoList.get(0);
            if (baseCategoryTwo != null && !baseCategoryTwo.getStatus().equals(GlobalConsts.YES)) {
                ServAssCategoryVO vo = new ServAssCategoryVO();
                vo.setCategId(baseCategoryTwo.getCategId());
                vo.setCategName(baseCategoryTwo.getName());
                categoryVOList.add(vo);
            }
            if (NumberUtil.isPositiveInteger(product.getCategOneId()) && NumberUtil.isPositiveInteger(product.getCategId())) {
                attrList = servProductBService.findAttrById(product.getCategOneId(), product.getCategId(), product.getChannelId());
            }
        }

        ServSubsidiaryGroupQuery subQuery = new ServSubsidiaryGroupQuery();
        subQuery.setType(ProductConsts.SERV_SUB_TYPE_HITCH);
        subQuery.setStatus(GlobalConsts.YES);
        List<ServSubsidiaryGroup> faults = servSubsidiaryGroupService.listByQuery(subQuery);

        subQuery.setType(ProductConsts.SERV_SUB_TYPE_GUARANTEE);
        List<ServSubsidiaryGroup> warrantys = servSubsidiaryGroupService.listByQuery(subQuery);
        List<Channel> channelList = channelService.listTwoLevelChannel(null, null);
        modelAndView.addObject("priceStatement", product.getPriceStatement());

        modelAndView.addObject("channelList", channelList);

        modelAndView.addObject("platList", GlobalConsts.getPlatList());
        modelAndView.addObject("attrList", attrList);
        modelAndView.addObject("ficoCategoryList", ficoCategoryList);
        modelAndView.addObject("servProductVO", servProductVO);
        modelAndView.addObject("servCategories", servCategories);
        modelAndView.addObject("baseCategories", baseCategories);
        modelAndView.addObject("categoryVOList", categoryVOList);
        modelAndView.addObject("faults", faults);
        modelAndView.addObject("warrantys", warrantys);
        List<String> unitList = listAllUnitName();
        modelAndView.addObject("unitList", unitList);
        modelAndView.addObject("flag", 1);
        modelAndView.addObject("bizTypeList", com.zmn.plat.common.dictionary.ProductDict.listBizType());

        return modelAndView;
    }

    /**
     * 描述: 产品添加，修改页面 跳转方法
     *
     * @param productId 产品id
     * @return modelAndView
     * @author tanbiao
     * @since 15:38 2019/9/22
     */
    @RequestMapping(value = "editDescView")
    public ModelAndView editDescView(@RequestParam(value = "productId", defaultValue = "0") Integer productId) {

        ServProduct product = productId > ProductDict.ZERO ? servProductService.findByKey(productId) : new ServProduct();
        ModelAndView modelAndView = new ModelAndView("product/show/productdesc");
        ServProductVO servProductVO = new ServProductVO();

        BeanUtils.copyProperties(product, servProductVO);

        modelAndView.addObject("servProductVO", servProductVO);
        modelAndView.addObject("flag", 2);
        return modelAndView;
    }

    /**
     * 描述：分类联动（服务分类查询一级产品分类）
     *
     * @param parentId 服务分类
     * @author tanbiao
     * @since 15:38 2019/9/22
     */
    @RequestMapping(value = "listChilds")
    public void listChilds(HttpServletRequest request, HttpServletResponse response,
                           @RequestParam(value = "parentId", defaultValue = "1") int parentId) {
        if (parentId == 0) {
            ResponseUtil.outWrite(response, "[]");
            return;
        }
        ServAssCategoryQuery query = new ServAssCategoryQuery();
        query.setServCategId(parentId);
        query.setCategOneStatus(GlobalConsts.YES);
        query.setShowType(ProductConsts.EC_PRODUCT_TYPE);
        List<KvDTO<Integer, String>> items = servAssCategoryService.listCateOneByQuery(query);

        StringBuilder sb = new StringBuilder("[");
        String jsonFormat = "[\"%s\",\"%s\"]%s ";

        for (int i = 0; i < items.size(); i++) {
            KvDTO<Integer, String> item = items.get(i);
            sb.append(String.format(jsonFormat, item.getKey(), item.getValue(), (i == items.size() - 1 ? "" : ",")));
        }
        sb.append("]");

        ResponseUtil.outWrite(response, sb.toString());
    }

    /**
     * 分类联动(根据一级产品分类ID和服务类型ID查询二级产品分类)
     *
     * @param categOneId  一级产品分类ID
     * @param servCategId 服务分类ID
     * @author tanbiao
     * @since 15:38 2019/9/22
     */
    @SuppressWarnings("Duplicates")
    @RequestMapping(value = "listCateChilds")
    public void listCateChilds(HttpServletRequest request, HttpServletResponse response,
                               @RequestParam(value = "categOneId", defaultValue = "1") int categOneId,
                               @RequestParam(value = "servCategId", defaultValue = "1") int servCategId) {
        if (servCategId == ProductDict.ZERO || categOneId == ProductDict.ZERO) {
            ResponseUtil.outWrite(response, "[]");
            return;
        }
        ServAssCategoryQuery query = new ServAssCategoryQuery();
        query.setCategOneId(categOneId);
        query.setServCategId(servCategId);
        query.setShowType(ProductConsts.EC_PRODUCT_TYPE);
        query.setCategTwoStatus(GlobalConsts.YES);
        List<ServAssCategoryVO> items = servAssCategoryService.listByQuery(query);

        StringBuilder sb = new StringBuilder("[");
        String jsonFormat = "[\"%s\",\"%s\"]%s ";
        ServAssCategoryVO item;
        String name;
        for (int i = 0; i < items.size(); i++) {
            item = items.get(i);
            name = item.getCategName();
            sb.append(String.format(jsonFormat, items.get(i).getCategId(), name, (i == items.size() - 1 ? "" : ",")));
        }
        sb.append("]");

        ResponseUtil.outWrite(response, sb.toString());
    }

    // /**
    // * 属性联动（一级产品分类和二级产品分类查询属性列表）
    // *
    // * @param categId, 二级产品分类ID
    // * @param categOneId 一级产品分类ID
    // * @author tanbiao
    // * @since 15:38 2019/9/22
    // */
    // @RequestMapping(value = "listAttrChilds")
    // public void listAttrChilds(HttpServletRequest request, HttpServletResponse response,
    // @RequestParam(value = "categId", defaultValue = "1") int categId, @RequestParam(value = "categOneId", defaultValue =
    // "1") int categOneId) {
    //
    // if (categId == ProductDict.ZERO || categOneId == ProductDict.ZERO) {
    // ResponseUtil.outWrite(response, "[]");
    // return;
    // }
    //
    // List<BaseCategoryAttributeVO> items = servProductBService.findAttrById(categOneId, categId);
    //
    // ResponseUtil.outWrite(response, JSONObject.toJSONString(items));
    // }

    /**
     * 描述: 根据条件导出工程师Excel
     *
     * @param query 查询条件
     * @author wangjie
     * @since 11:43 2019/2/19
     **/
    @RequestMapping(value = "outputExcel")
    // @RequiresPermissions("/showProduct/outputExcel.action")
    public void outputExcel(HttpServletResponse response, ServProductQuery query) {

        // 前端产品类型
        query.setShowType(ProductConsts.EC_PRODUCT_TYPE);
        query.setPageSize(getExportPageLimit(response));

        ArrayList<List> lists = servProductBService.outputShowProductExcel(query);
        try {
            String name = "前台产品报表.xlsx";
            name = new String(name.getBytes(), "ISO8859-1");
            ExcelUtil.export(response, lists, name, "sheet");
        } catch (Exception e) {
            LoggerUtil.error(this.getClass(), "导出报表出错" + e.getMessage(), e);
        }
    }


    @RequestMapping(value = "categorylist")
    public ModelAndView categorylist(@RequestParam(value = "type") Integer type,
                                     @RequestParam(value = "productId") Integer productId,
                                     @RequestParam(value = "titleIndex", required = false) Integer titleIndex) {

        ModelAndView modelAndView = new ModelAndView("product/show/select_category");
        // 选中第一个头
        if (Objects.isNull(titleIndex)) {
            titleIndex = type * 10;
        }
        modelAndView.addObject("heads", listHeader(type));
        modelAndView.addObject("productId", productId);
        modelAndView.addObject("type", type);
        modelAndView.addObject("titleIndex", titleIndex);
        modelAndView.addObject("servCategorys", getAllChildCategory());
        return modelAndView;
    }

    private List<KvDTO> listHeader(int type) {
        if (type == 2) {
            return ProductTitleDict.listProductPicTitle();
        } else if (type == 3) {
            return ProductTitleDict.listProductGurenteeTitle();
        }
        return Collections.emptyList();
    }

    private List<KvDTO<Integer, String>> getAllChildCategory() {
        ServAssCategoryQuery categoryQuery = new ServAssCategoryQuery();
        categoryQuery.setCategOneStatus(GlobalConsts.YES);
        categoryQuery.setCategTwoStatus(GlobalConsts.YES);
        categoryQuery.setShowType(ProductDict.EC_PRODUCT_TYPE);
        categoryQuery.setServCategShowStatus(GlobalConsts.YES);

        List<ServAssCategoryVO> voList = servAssCategoryService.listByQuery(categoryQuery);
        // 按服务分类分组
        Map<Integer, List<ServAssCategoryVO>> serviceCategoryMap = voList.stream().collect(groupingBy(ServAssCategory::getServCategId));

        List<KvDTO<Integer, String>> ret = serviceCategoryMap.values().stream().map(serviceCategory -> {
            // 按一级分类分组
            Map<Integer, List<ServAssCategoryVO>> categoryOneMap =
                    serviceCategory.stream().collect(groupingBy(ServAssCategory::getCategOneId));

            List<KvDTO> categoryOneList = categoryOneMap.values().stream().map(categoryOne -> {
                // 二级分类KvDTO
                List<KvDTO> categList =
                        categoryOne.stream().map(p -> new KvDTO(p.getCategId(), p.getCategName())).collect(Collectors.toList());
                // 一级分类KvDTO
                KvDTO categOne = new KvDTO<>(categoryOne.get(0).getCategOneId(), categoryOne.get(0).getCategOneName());
                categOne.setChildren(categList);
                return (KvDTO<Integer, String>) categOne;
            }).collect(Collectors.toList());

            // 服务分类KvDTO
            KvDTO dto = new KvDTO<>(serviceCategory.get(0).getServCategId(), serviceCategory.get(0).getServCategName());
            dto.setChildren(categoryOneList);
            return (KvDTO<Integer, String>) dto;
        }).collect(Collectors.toList());
        return ret;
    }

}
